﻿using NUnit.Framework;
using System.Text;
using TI_BLE_HCI_ClientLib.HCICommands;

namespace TI_BLE_HCI_ClientLib.Tests
{
    [TestFixture]
    public class HCICommandsEncodingTester
    {
        [Test]
        public void Encode_HCICommand_GAP_Device_Init()
        {
            string hex = "01 00 FE 26 08 05 00 00 00 00 00 00 00 00 00 00 " +
                         "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " +
                         "00 00 00 00 00 00 01 00 00 00 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GAP_Device_Init hciCommandGAPDeviceInit = new HCICommand_GAP_Device_Init(
                HCICommand_GAP_Device_Init.ProfileRoleEnum.GAPProfileCentral,
                5,
                TestHelpers.StringWithColonsToByteArrayReversed("00,00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"),
                TestHelpers.StringWithColonsToByteArrayReversed("00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"),
                1);

            Assert.AreEqual(buf, hciCommandGAPDeviceInit.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GAP_Device_Discovery_Request()
        {
            string hex = "01 04 FE 03 03 01 00 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GAP_Device_Discovery_Request hciCommandGAPDeviceDiscoveryRequest = new HCICommand_GAP_Device_Discovery_Request(
                HCICommand_GAP_Device_Discovery_Request.ModeEnum.ScanForAllDevices,
                HCICommand_GAP_Device_Discovery_Request.ActiveScanEnum.TurnOnActiveScanning,
                HCICommand_GAP_Device_Discovery_Request.WhiteListEnum.DontUseWhiteListDuringScanning);

            Assert.AreEqual(buf, hciCommandGAPDeviceDiscoveryRequest.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GAP_Establish_Link_Request()
        {
            string hex = "01 09 FE 09 00 00 00 90 D5 EC 30 18 00 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GAP_Establish_Link_Request hciCommandGAPEstablishLinkRequest = new HCICommand_GAP_Establish_Link_Request(
                HCICommand_GAP_Establish_Link_Request.HighDutyCycleEnum.Disabled,
                HCICommand_GAP_Establish_Link_Request.WhiteListEnum.DontUseWhiteList,
                HCICommand_GAP_Establish_Link_Request.AddrTypePeerEnum.AddrType_Public,
                TestHelpers.StringWithColonsToByteArrayReversed("00:18:30:EC:D5:90"));

            Assert.AreEqual(buf, hciCommandGAPEstablishLinkRequest.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GAP_Terminate_Link_Request()
        {
            string hex = "01 0A FE 03 00 00 13 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GAP_Terminate_Link_Request hciCommandGAPTerminateLinkRequest = new HCICommand_GAP_Terminate_Link_Request(
                0x0000,
                HCICommand_GAP_Terminate_Link_Request.ReasonEnum.RemoteUserTerminatedConnection);

            Assert.AreEqual(buf, hciCommandGAPTerminateLinkRequest.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GATT_Discovery_Characteristics_by_UUID()
        {
            string hex = "01 88 FD 08 00 00 01 00 FF FF F1 FF ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Discover_Characteristics_by_UUID hciCommandGATTDiscoveryCharacteristicsByUUID =
                new HCICommand_GATT_Discover_Characteristics_by_UUID(
                    0x0000,
                    0x0001,
                    0xFFFF,
                    TestHelpers.StringWithColonsToByteArray("F1:FF"));

            Assert.AreEqual(buf, hciCommandGATTDiscoveryCharacteristicsByUUID.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GATT_Read_Characteristic_Value_Request()
        {
            string hex = "01 8A FD 04 00 00 03 00 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Read_Characteristic_Value_Request hciCommandGATTReadCharacteristicValueRequest =
                new HCICommand_GATT_Read_Characteristic_Value_Request(
                    0x0000,
                    0x0003);

            Assert.AreEqual(buf, hciCommandGATTReadCharacteristicValueRequest.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GATT_Write_Characteristic_Value_Request()
        {
            string hex = "01 92 FD 05 00 00 28 00 01 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Write_Characteristic_Value_Request hciCommandGATTWriteCharacteristicValueRequest =
                new HCICommand_GATT_Write_Characteristic_Value_Request(
                    0x0000,
                    0x0028,
                    new byte[] { 1 });

            Assert.AreEqual(buf, hciCommandGATTWriteCharacteristicValueRequest.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GAP_Make_Discoverable()
        {
            string hex = "01 06 FE 0A 00 00 00 00 00 00 00 00 07 00 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GAP_Make_Discoverable hciCommandGAPMakeDiscoverable =
                new HCICommand_GAP_Make_Discoverable(
                    HCICommand_GAP_Make_Discoverable.EventTypeEnum.ConnectableUndirectedAdvertisement,
                    HCICommand_GAP_Make_Discoverable.InitiatorAddrTypeEnum.ADDRTYPE_PUBLIC,
                    new byte[] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
                    HCICommand_GAP_Make_Discoverable.ChannelMapEnum.Channel37 | HCICommand_GAP_Make_Discoverable.ChannelMapEnum.Channel38 | HCICommand_GAP_Make_Discoverable.ChannelMapEnum.Channel39,
                    HCICommand_GAP_Make_Discoverable.FilterPolicyEnum.AllowScanFromAnyAllowConnectRequestFromAny);

            Assert.AreEqual(buf, hciCommandGAPMakeDiscoverable.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GAP_Update_Advertising_Data()
        {
            string hex = "01 07 FE 05 01 03 02 01 06 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GAP_Update_Advertising_Data hciCommandGAPUpdateAdvertisingData =
                new HCICommand_GAP_Update_Advertising_Data(
                   HCICommand_GAP_Update_Advertising_Data.AdvertisingTypeEnum.AdvertisementData,
                   new byte[] { 0x2, 0x1, 0x6 });

            Assert.AreEqual(buf, hciCommandGAPUpdateAdvertisingData.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GAP_Add_Service()
        {
            string hex = "01 FC FD 04 00 28 03 00 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Add_Service hciCommandGATTAddService =
                new HCICommand_GATT_Add_Service(
                   HCICommand_GATT_Add_Service.UUIDEnum.PRIMARY_SERVICE,
                   3);

            Assert.AreEqual(buf, hciCommandGATTAddService.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GAP_Add_Attribute()
        {
            string hex = "01 FE FD 03 00 2A 03 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Add_Attribute hciCommandGATTAddAttribute =
                new HCICommand_GATT_Add_Attribute(
                    0x2A00,
                    HCICommand_GATT_Add_Attribute.PermissionsEnum.GATT_PERMIT_READ | HCICommand_GATT_Add_Attribute.PermissionsEnum.GATT_PERMIT_WRITE);

            Assert.AreEqual(buf, hciCommandGATTAddAttribute.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GATT_Read_Characteristic_Value_Response()
        {
            string hex = "01 0B FD 08 00 00 01 02 03 04 05 06 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Read_Characteristic_Value_Response hciCommandGATTReadCharacteristicValueResponse =
                new HCICommand_GATT_Read_Characteristic_Value_Response(
                    0x0000,
                    new byte[] { 1, 2, 3, 4, 5, 6 });

            Assert.AreEqual(buf, hciCommandGATTReadCharacteristicValueResponse.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_GATT_Write_Characteristic_Value_Response()
        {
            string hex = "01 13 FD 02 00 00 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Write_Characteristic_Value_Response hciCommandGATTWriteCharacteristicValueResponse =
                new HCICommand_GATT_Write_Characteristic_Value_Response(
                    0x0000);

            Assert.AreEqual(buf, hciCommandGATTWriteCharacteristicValueResponse.ToByteArray());
        }


        [Test]
        public void Encode_HCICommand_ATT_ReadByGroupTypeResponse()
        {
            string hex = "01 11 FD 15 00 00 06 01 00 0B 00 00 18 0C 00 0F 00 01 18 10 00 22 00 0A 18 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Read_By_Group_Type_Response hciCommandReadByGroupTypeResponse = new HCICommand_GATT_Read_By_Group_Type_Response(
                0x0000,
                6,
                new byte[]
                {
                    0x01,0x00,0x0B,0x00,0x00,0x18,
                    0x0C,0x00,0x0F,0x00,0x01,0x18,
                    0x10,0x00,0x22,0x00,0x0A,0x18
                });

            Assert.AreEqual(buf, hciCommandReadByGroupTypeResponse.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_ATT_ReadByGroupTypeResponse_2()
        {
            string hex = "01 11 FD 15 00 00 06 01 00 0B 00 00 18 0C 00 0F 00 01 18 10 00 22 00 0A 18 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Read_By_Group_Type_Response hciCommandReadByGroupTypeResponse = new HCICommand_GATT_Read_By_Group_Type_Response(
                0x0000,
                new HCICommand_GATT_Read_By_Group_Type_Response.AttributeGroupData[]
                {
                    new HCICommand_GATT_Read_By_Group_Type_Response.AttributeGroupData(0x0001,0x000B,0x1800),
                    new HCICommand_GATT_Read_By_Group_Type_Response.AttributeGroupData(0x000C,0x000F,0x1801),
                    new HCICommand_GATT_Read_By_Group_Type_Response.AttributeGroupData(0x0010,0x0022,0x180A)
                });

            Assert.AreEqual(buf, hciCommandReadByGroupTypeResponse.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_ATT_FindByTypeValueResponse()
        {
            string hex = "01 07 FD 06 00 00 01 00 0B 00 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Find_By_Type_Value_Response hciCommandFindByTypeValueResponse = new HCICommand_GATT_Find_By_Type_Value_Response(
                0x0000,
                new HCICommand_GATT_Find_By_Type_Value_Response.HandlesInfo[]
                {
                    new HCICommand_GATT_Find_By_Type_Value_Response.HandlesInfo(0x0001,0x000B)
                });

            Assert.AreEqual(buf, hciCommandFindByTypeValueResponse.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_ATT_ReadByTypeResponse()
        {
            string hex = "01 09 FD 0A 00 00 07 02 00 02 03 00 00 2A ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Read_By_Type_Response hciCommandReadByTypeResponse = new HCICommand_GATT_Read_By_Type_Response(
                0x0000,
                new HCICommand_GATT_Read_By_Type_Response.AttributeData[]
                {
                    new HCICommand_GATT_Read_By_Type_Response.AttributeData(0x0002,new byte[] {0x02,0x03, 0x00, 0x00, 0x2A})
                });

            Assert.AreEqual(buf, hciCommandReadByTypeResponse.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_HCIEXT_SystemReset()
        {
            string hex = "01 1D FC 01 00 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_HCIEXT_SystemReset hciCommandSystemReset = new HCICommand_HCIEXT_SystemReset(HCICommand_HCIEXT_SystemReset.ResetTypeEnum.HARD_RESET);

            Assert.AreEqual(buf, hciCommandSystemReset.ToByteArray());
        }

        [Test]
        public void Encode_HCICommand_ATT_HandleValueNotification()
        {
            string hex = "01 1B FD 06 00 00 00 05 00 07 ";

            byte[] buf = TestHelpers.StringToByteArray(hex);

            HCICommand_GATT_Handle_Value_Notification hciCommandHandleValueNotification = new HCICommand_GATT_Handle_Value_Notification(0x0000,0x0005,7,false);

            Assert.AreEqual(buf, hciCommandHandleValueNotification.ToByteArray());
        }
    }
}
